home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fritz: All Fritz
/
All Fritz.zip
/
All Fritz
/
FILES
/
PROGMISC
/
FORTRAN1.LZH
/
EVAL.FOR
< prev
next >
Wrap
Text File
|
1988-02-08
|
8KB
|
285 lines
SUBROUTINE EVAL (TOKE, NTOKE, FACTS, TOP, NT, BOT, NB, FAC )
C*
C* *******************************
C* *******************************
C* ** **
C* ** EVAL **
C* ** **
C* *******************************
C* *******************************
C*
C* SUBPROGRAM :
C* EVALUATE
C*
C* AUTHOR :
C* ART RAGOSTA
C* MS 207-5
C* AMES RESEARCH CENTER
C* MOFFETT FIELD, CALIF 94035
C* (415) 694-5578
C*
C* PURPOSE :
C* TO EVALUATE THE REVERSE POLISH STRING, RESULTING IN A
C* FINAL SCALE FACTOR AND THE PROPER UNITS.
C*
C* METHODOLOGY :
C* NA
C*
C* INPUT ARGUMENTS :
C* TOKE - THE LIST OF TOKENS IN REVERSE POLISH
C* NTOKE - THE NUMBER OF TOKENS IN 'TOKE'
C* FACTS - THE SCALE FACTORS FOR EACH ENTRY IN 'TOKE'
C*
C* OUTPUT ARGUMENTS :
C* TOP - THE LIST OF UNITS WHICH ARE IN THE NUMERATOR
C* NT - THE NUMBER OF ENTRIES IN 'TOP'
C* BOT - THE LIST OF UNITS WHICH ARE IN THE DENOMINATOR
C* NB - THE NUMBER OF ENTRIES IN 'BOT'
C* FAC - THE TOTAL SCALE FACTOR
C*
C* INTERNAL WORK AREAS :
C* TFAC, BFAC - STACKS FOR SCALE FACTORS
C* TSTACK, BSTACK - STACKS FOR UNIT STRINGS
C*
C* COMMON BLOCKS :
C* NONE
C*
C* FILE REFERENCES :
C* NONE
C*
C* SUBPROGRAM REFERENCES :
C* LENGTH, RIGHT
C*
C* ERROR PROCESSING :
C* NONE
C*
C* TRANSPORTABILITY LIMITATIONS :
C* NONE
C*
C* ASSUMPTIONS AND RESTRICTIONS :
C* NONE
C*
C* LANGUAGE AND COMPILER :
C* ANSI FORTRAN 77
C*
C* VERSION AND DATE :
C* VERSION I.0 7-FEB-85
C*
C* CHANGE HISTORY :
C* 7-FEB-85 INITIAL VERSION
C*
C***********************************************************************
C*
CHARACTER *600 BSTACK(50), TSTACK(50), T, T1, B, B1
CHARACTER *6 TOKE(1), TOP(1), BOT(1), TT
DOUBLE PRECISION FACTS(1), FAC, FSTACK(50)
C
FAC = 1.0D0
NT = 0
NB = 0
IF ( NTOKE .LE. 0 ) RETURN
ISP = 0
C
C --- FIRST PASS, CALCULATE SCALE FACTOR
C
DO 100 I = 1, NTOKE
C
C ----- FOR EXPONENTIATION, GET EXPONENT FROM TOKENS
C
IF ( TOKE(I) .EQ. '^') THEN
TT = TOKE(I-1)
CALL RIGHT ( TT )
READ ( TT, 900, ERR=1000 ) NUM
FSTACK(ISP) = FSTACK(ISP)**NUM
C
C ----- MULTIPLY
C
ELSE IF (TOKE(I) .EQ. '*') THEN
ISP = ISP - 1
FSTACK(ISP) = FSTACK(ISP) * FSTACK(ISP+1)
C
C ----- DIVIDE
C
ELSE IF (TOKE(I) .EQ. '/') THEN
ISP = ISP - 1
FSTACK(ISP) = FSTACK(ISP) / FSTACK(ISP+1)
C
C ----- OTHERWISE THE TOKEN IS A UNIT
C
ELSE
C
C -------- IF THE TOKEN IS NUMERIC, DO NOTHING---
C -------- IF IT IS ALPHA, ADD FACTOR TO STACK
C
IF ((TOKE(I)(1:1) .LT. '0') .OR.
$ (TOKE(I)(1:1) .GT. '9')) THEN
ISP = ISP + 1
FSTACK(ISP) = FACTS(I)
ENDIF
ENDIF
100 CONTINUE
FAC = FSTACK(ISP)
C
C --- PASS 2, DETERMINE WHICH SYMBOLS ARE IN NUMERATOR AND DENOMINATOR
C
NT = 0
NB = 0
ISP = 0
DO 200 I = 1, NTOKE
C
C ----- FOR EXPONENTIATION, ADD THE STRING TO ITSELF 'NUM' TIMES.
C
IF ( TOKE(I) .EQ. '^') THEN
TT = TSTACK(ISP)
ISP = ISP - 1
CALL RIGHT ( TT )
READ ( TT, 900, ERR=1000 ) NUM
T1 = TSTACK(ISP)
B1 = BSTACK(ISP)
ISP = ISP - 1
T = ' '
B = ' '
IT = 1
IB = 1
LT = LENGTH(T1)
LB = LENGTH(B1)
IF (LT .GT. 0) THEN
DO 10 II = 1, NUM
T(IT:IT+LT-1) = T1(1:LT)
IT = IT + LT
T(IT:IT) = '*'
IT = IT + 1
10 CONTINUE
ENDIF
IF (LB .GT. 0) THEN
DO 15 II = 1, NUM
B(IB:IB+LB-1) = B1(1:LB)
IB = IB + LB
B(IB:IB) = '*'
IB = IB + 1
15 CONTINUE
ENDIF
IT = IT - 1
IB = IB - 1
T(IT:IT) = ' '
B(IB:IB) = ' '
ISP = ISP + 1
TSTACK(ISP) = T
BSTACK(ISP) = B
C
C ----- FOR A MULTIPLY, ADD STRINGS FROM THE SAME SIDE OF THE STACK.
C
ELSE IF (TOKE(I) .EQ. '*') THEN
T = TSTACK(ISP)
B = BSTACK(ISP)
ISP = ISP - 1
T1 = TSTACK(ISP)
B1 = BSTACK(ISP)
ISP = ISP - 1
LT = LENGTH ( T )
LB = LENGTH ( B )
LT1 = LENGTH ( T1 )
LB1 = LENGTH ( B1 )
C
C -------- CHECK TO SEE THAT THERE WAS AN ENTRY IN BOTH LOCATIONS
C
IF ((LT .GT. 0) .AND. (LT1 .GT. 0)) THEN
LT = LT + 1
T(LT:LT) = '*'
ENDIF
IF ((LB .GT. 0) .AND. (LB1 .GT. 0)) THEN
LB = LB + 1
B(LB:LB) = '*'
ENDIF
LT = LT + 1
LB = LB + 1
IF (LT1 .GT. 0) THEN
T(LT:LT+LT1-1) = T1(1:LT1)
ENDIF
IF (LB1 .GT. 0) THEN
B(LB:LB+LB1-1) = B1(1:LB1)
ENDIF
ISP = ISP + 1
TSTACK(ISP) = T
BSTACK(ISP) = B
C
C ----- FOR A DIVIDE, ADD STRINGS FROM OPPOSITE SIDES OF THE STACK.
C
ELSE IF (TOKE(I) .EQ. '/') THEN
T = TSTACK(ISP)
B = BSTACK(ISP)
ISP = ISP - 1
T1 = TSTACK(ISP)
B1 = BSTACK(ISP)
ISP = ISP - 1
LT = LENGTH ( T )
LB = LENGTH ( B )
LT1 = LENGTH ( T1 )
LB1 = LENGTH ( B1 )
IF ((LT1 .GT. 0) .AND. (LB .GT. 0)) THEN
LT1 = LT1 + 1
T1(LT1:LT1) = '*'
ENDIF
IF ((LB1 .GT. 0) .AND. (LT .GT. 0)) THEN
LB1 = LB1 + 1
B1(LB1:LB1) = '*'
ENDIF
LT1 = LT1 + 1
LB1 = LB1 + 1
IF (LB .GT. 0 ) THEN
T1(LT1:LT1+LB-1) = B(1:LB)
ENDIF
IF (LT .GT. 0 ) THEN
B1(LB1:LB1+LT-1) = T(1:LT)
ENDIF
ISP = ISP + 1
TSTACK(ISP) = T1
BSTACK(ISP) = B1
C
C ----- OTHERWISE THE TOKEN IS A UNIT, PUT IT ON THE TOP SIDE OF STACK
C
ELSE
ISP = ISP + 1
TSTACK(ISP) = TOKE(I)
BSTACK(ISP) = ' '
ENDIF
200 CONTINUE
C
C --- NOW PARSE THE TOP STRINGS INTO ARRAYS OF UNITS
C
T = TSTACK(ISP)
B = BSTACK(ISP)
LT = LENGTH ( T )
LB = LENGTH ( B )
NT = 0
NB = 0
I = 1
205 NT = NT + 1
INT = 1
TOP(NT) = ' '
210 TOP(NT)(INT:INT) = T(I:I)
INT = INT + 1
I = I + 1
IF (I .GT. LT) GO TO 250
IF (T(I:I) .NE. '*') GO TO 210
I = I + 1
IF (I .LE. LT) GO TO 205
C
250 I = 1
300 NB = NB + 1
INT = 1
BOT(NB) = ' '
310 BOT(NB)(INT:INT) = B(I:I)
INT = INT + 1
I = I + 1
IF (I .GT. LB) GO TO 1000
IF (B(I:I) .NE. '*') GO TO 310
I = I + 1
IF (I .LE. LB) GO TO 300
1000 RETURN
900 FORMAT ( I6 )
END
C
C---END EVAL
C